package com.zk.zookeeper.curb;

import org.apache.log4j.Logger;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.apache.zookeeper.server.command.WatchCommand;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;

import org.junit.Test;

import javax.xml.ws.Action;
import java.io.IOException;
import java.util.List;

public class ZKCurb {
//    会话超时时间
    private final static int SESSION_TIME = 3000;
//    定义zk集群ip地址
    private final static String ZK_SERVERS = "192.168.85.102:2181,192.168.85.103:2181,192.168.85.104:2181";
//      日志对象
    private final static Logger LOGGER = Logger.getLogger(ZKCurb.class);
    private ZooKeeper zkCli = null;
    private Watcher watcher = new Watcher() {
        @Override
        public void process(WatchedEvent watchedEvent) {
            LOGGER.info("event:"+watchedEvent.toString());
        }
    };

    @Before
    public void connect() throws IOException {
        zkCli = new ZooKeeper(ZK_SERVERS,SESSION_TIME,watcher);
//        获取当前会话
        long sessionld = zkCli.getSessionId();
        LOGGER.info("sessionid:"+sessionld);
//        System.out.println("zkCli:"+zkCli);
    }

    @After
    public void close() throws InterruptedException {
        zkCli.close();
    }
    /*
    创建节点
    final String path  要创建节点的路径
    byte data[]  节点中数据的内容
    List<ACL> acl  节点的权限
    CreateMode createMode  节点类型
           * PERSISTENT:普通持久节点
           * PERSISTENT_SEQUENTIAL：顺序持久节点
           * EPHEMERAL：普通临时节点
           * EPHEMERAL_SEQUENTIAL：顺序临时节点
     */

    public void creat()  {
        String result = "";
        try {
//            result = zkCli.create("/zk002", "good".getBytes(),
//                    ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            result = zkCli.create("/temp_node001", "good".getBytes(),
                    ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
        } catch (Exception e) {

            LOGGER.error(e.getMessage());
            // 抛出AssertionError
            Assert.fail();

        }
        LOGGER.info("create result:{"+result+"}");

    }

    @Test
    public void exist(){
        try {
//            Stat stat = zkCli.exists("/bjsxt", false);
            Stat stat = zkCli.exists("/zk002", false);
            if (stat == null){
                System.out.println("/bjsxt not exists");
            }
            else {
                System.out.println("/bjsxt exists" );
            }
        } catch (Exception e) {
            LOGGER.error(e.getMessage());
        }
    }



    @Test
    public void getData(){
        String result = null;
        try {
            byte[] data = zkCli.getData("/zk002", null, null);
            result = new String(data);
        } catch (KeeperException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        LOGGER.info("getData result------{"+result+"}");

    }

    @Test
    public void getStat(){
        String result = null;
        Stat stat = new Stat();
        try {
            byte[] data = zkCli.getData("/zk002", null, stat);
            result = new String(data);
        } catch (KeeperException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        LOGGER.info("getData result------{"+result+"}");
        LOGGER.info("getData result------{"+stat+"}");

    }

//    获取子节点名称
    @Test
    public void getchildren(){
        try {
            // 获取所有子节点
            List<String> childrenList = zkCli.getChildren("/", true);
            // 遍历子节点
            for (String child:childrenList){
                LOGGER.info("chile:{"+child+"}");
            }
        } catch (KeeperException e) {
            LOGGER.error(e.getMessage());
        } catch (InterruptedException e) {
            LOGGER.error(e.getMessage());
        }
    }

//  获取子节点信息
    @Test
    public void getchildrenData(){
        try {
            // 获取所有子节点
            List<String> childrenList = zkCli.getChildren("/", true);
            String data = null;
            // 遍历子节点
            for (String child:childrenList){
                data = new String(zkCli.getData("/" + child, null, null));
                LOGGER.info("chile:{"+child+"},value:{"+data+"}");
            }
        } catch (KeeperException e) {
            LOGGER.error(e.getMessage());
        } catch (InterruptedException e) {
            LOGGER.error(e.getMessage());
        }
    }
    @Test
    public void setData(){
        Stat stat = null;
        // path:被修改节点的全路径， 第二个参数:修改后的value，version:-1表示不管任何版本均可修改
        try {
            stat = zkCli.setData("/zk002","setData01".getBytes(),-1);
        } catch (KeeperException e) {
//            将错误信息打印出来
            LOGGER.error(e.getMessage());
        } catch (InterruptedException e) {
            LOGGER.error(e.getMessage());
        }
        //  getVersion获取的是dataVersion的值，代表节点值的版本，每次被修改该节点值+1
        LOGGER.info("version:{"+stat.getVersion()+"}");
    }

    @Test
    public void delete(){
        try {
            zkCli.delete("/zk/tanke0000000009",-1);
            System.out.println("删除成功");
        } catch (InterruptedException e) {
            LOGGER.error(e.getMessage());
        } catch (KeeperException e) {
            LOGGER.error(e.getMessage());
        }
    }

    @Test
    public void getDataWatcher(){
        String result = null;
        byte[] data = new byte[0];
        try {
            data = zkCli.getData("/zk002", new Watcher() {
                @Override
                public void process(WatchedEvent event) {
                    LOGGER.info("getDataWatcher event type:{"+event.getType()+"}");
                    System.out.println("watcher ok!");
                }
            }, null);
            result = new String(data);
        } catch (KeeperException e) {
            LOGGER.error(e.getMessage());
            // 捕获到错误就结束运行
            Assert.fail();
        } catch (InterruptedException e) {
            LOGGER.error(e.getMessage());
            Assert.fail();
        }
        LOGGER.info("getData result:{"+result+"}");

        try {
            System.out.println("-------set1-------");
            zkCli.setData("/zk002","updata1".getBytes(),-1);
            System.out.println("-------set2-------");
            zkCli.setData("/zk002","updata2".getBytes(),-1);
        } catch (KeeperException e) {
            LOGGER.error(e.getMessage());
            Assert.fail();
        } catch (InterruptedException e) {
            LOGGER.error(e.getMessage());
            Assert.fail();
        }
        System.out.println("test over");
        try {
            Thread.sleep(30000);
        }catch (InterruptedException e) {
            LOGGER.error(e.getMessage());
        }

    }


}
